#include <QCoreApplication>
#include <QElapsedTimer>
#include <QTimer>
#include <QDebug>
#include <QProcess>
#include <QFile>
#include <QTextStream>
#include <QDateTime>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QThread>

class AdvancedRTSPLatencyTester : public QObject
{
    Q_OBJECT

public:
    AdvancedRTSPLatencyTester(QObject *parent = nullptr) 
        : QObject(parent), 
          m_rtspUrl("rtsp://192.168.226.141:8554/camera_test"),
          m_testDuration(30000), // 30 seconds
          m_testInterval(1000)   // 1 second
    {
        m_gstPath = "D:\\gstreamer\\1.0\\mingw_x86_64\\bin\\";
    }

    void runTest()
    {
        qDebug() << "=== 高级RTSP流媒体延迟测试工具 ===";
        qDebug() << "测试URL:" << m_rtspUrl;
        qDebug() << "测试时长:" << m_testDuration << "ms";
        qDebug() << "测试间隔:" << m_testInterval << "ms";
        qDebug() << "================================";

        m_testTimer = new QTimer(this);
        connect(m_testTimer, &QTimer::timeout, this, &AdvancedRTSPLatencyTester::performSingleTest);
        
        m_timeoutTimer = new QTimer(this);
        connect(m_timeoutTimer, &QTimer::timeout, this, &AdvancedRTSPLatencyTester::finishTest);
        
        m_elapsedTimer.start();
        m_timeoutTimer->start(m_testDuration);
        m_testTimer->start(m_testInterval);
        
        // 开始第一次测试
        performSingleTest();
    }

private slots:
    void performSingleTest()
    {
        qDebug() << "\n[" << (m_measurements.size() + 1) << "] 执行延迟测试...";
        
        Measurement measurement;
        measurement.timestamp = QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
        
        // 测量网络延迟
        double networkLatency = measureNetworkLatency();
        if (networkLatency >= 0) {
            measurement.networkLatency = networkLatency;
            qDebug() << "  网络延迟:" << networkLatency << "ms";
        }
        
        // 测量GStreamer管道延迟
        double pipelineLatency = measureGstPipelineLatency();
        if (pipelineLatency >= 0) {
            measurement.pipelineLatency = pipelineLatency;
            qDebug() << "  GStreamer管道延迟:" << pipelineLatency << "ms";
        }
        
        // 计算总延迟
        double totalLatency = 0;
        if (networkLatency >= 0) totalLatency += networkLatency;
        if (pipelineLatency >= 0) totalLatency += pipelineLatency;
        measurement.totalLatency = totalLatency;
        
        qDebug() << "  总延迟:" << totalLatency << "ms";
        
        m_measurements.append(measurement);
    }
    
    void finishTest()
    {
        m_testTimer->stop();
        m_timeoutTimer->stop();
        
        generateAnalysisReport();
        
        QCoreApplication::quit();
    }

private:
    struct Measurement {
        QString timestamp;
        double networkLatency = -1;
        double pipelineLatency = -1;
        double totalLatency = -1;
    };
    
    QString m_rtspUrl;
    QString m_gstPath;
    int m_testDuration;
    int m_testInterval;
    QTimer *m_testTimer;
    QTimer *m_timeoutTimer;
    QElapsedTimer m_elapsedTimer;
    QList<Measurement> m_measurements;
    
    double measureNetworkLatency()
    {
        // 从RTSP URL中提取主机名
        QString host = m_rtspUrl;
        host = host.replace("rtsp://", "");
        int portPos = host.indexOf(":");
        if (portPos > 0) {
            host = host.left(portPos);
        } else {
            int pathPos = host.indexOf("/");
            if (pathPos > 0) {
                host = host.left(pathPos);
            }
        }
        
        // 执行ping命令
        QString cmd = QString("ping -n 4 %1").arg(host);
        QProcess pingProcess;
        pingProcess.start(cmd);
        pingProcess.waitForFinished(5000); // 5秒超时
        
        if (pingProcess.exitCode() == 0) {
            QString output = pingProcess.readAllStandardOutput();
            // 解析ping输出获取平均延迟
            QRegExp rx("平均 = (\\d+)ms");
            if (rx.indexIn(output) >= 0) {
                return rx.cap(1).toDouble();
            }
            // 尝试英文格式
            rx.setPattern("Average = (\\d+)ms");
            if (rx.indexIn(output) >= 0) {
                return rx.cap(1).toDouble();
            }
        }
        
        return -1;
    }
    
    double measureGstPipelineLatency()
    {
        // 创建一个临时的GStreamer管道来测量延迟
        QString pipeline = QString(
            "rtspsrc location=%1 latency=0 ! "
            "rtpjitterbuffer latency=0 ! "
            "rtph264depay ! "
            "avdec_h264 ! "
            "videoconvert ! "
            "fakesink sync=false"
        ).arg(m_rtspUrl);
        
        QString cmd = QString("\"%1gst-launch-1.0.exe\" %2").arg(m_gstPath, pipeline);
        
        QElapsedTimer timer;
        timer.start();
        
        QProcess gstProcess;
        gstProcess.start(cmd);
        
        // 等待一段时间让管道启动
        gstProcess.waitForStarted(3000);
        
        if (gstProcess.state() == QProcess::Running) {
            // 等待一小段时间让管道处理数据
            QThread::msleep(2000);
            
            // 测量这段时间
            qint64 elapsed = timer.elapsed();
            
            // 终止进程
            gstProcess.kill();
            gstProcess.waitForFinished(1000);
            
            return elapsed;
        }
        
        return -1;
    }
    
    void generateAnalysisReport()
    {
        qDebug() << "\n" << QString("=").repeated(60);
        qDebug() << "RTSP流媒体延迟分析报告";
        qDebug() << QString("=").repeated(60);
        
        // 基本统计信息
        int totalTests = m_measurements.size();
        qDebug() << "总测试次数:" << totalTests;
        
        // 网络延迟统计
        QList<double> networkLatencies;
        for (const auto &m : m_measurements) {
            if (m.networkLatency >= 0) {
                networkLatencies.append(m.networkLatency);
            }
        }
        
        if (!networkLatencies.isEmpty()) {
            double avgNetwork = 0;
            double minNetwork = networkLatencies.first();
            double maxNetwork = networkLatencies.first();
            
            for (double lat : networkLatencies) {
                avgNetwork += lat;
                if (lat < minNetwork) minNetwork = lat;
                if (lat > maxNetwork) maxNetwork = lat;
            }
            avgNetwork /= networkLatencies.size();
            
            qDebug() << "\n网络延迟统计:";
            qDebug() << "  平均延迟:" << QString::number(avgNetwork, 'f', 2) << "ms";
            qDebug() << "  最小延迟:" << QString::number(minNetwork, 'f', 2) << "ms";
            qDebug() << "  最大延迟:" << QString::number(maxNetwork, 'f', 2) << "ms";
        }
        
        // 管道延迟统计
        QList<double> pipelineLatencies;
        for (const auto &m : m_measurements) {
            if (m.pipelineLatency >= 0) {
                pipelineLatencies.append(m.pipelineLatency);
            }
        }
        
        if (!pipelineLatencies.isEmpty()) {
            double avgPipeline = 0;
            double minPipeline = pipelineLatencies.first();
            double maxPipeline = pipelineLatencies.first();
            
            for (double lat : pipelineLatencies) {
                avgPipeline += lat;
                if (lat < minPipeline) minPipeline = lat;
                if (lat > maxPipeline) maxPipeline = lat;
            }
            avgPipeline /= pipelineLatencies.size();
            
            qDebug() << "\nGStreamer管道延迟统计:";
            qDebug() << "  平均延迟:" << QString::number(avgPipeline, 'f', 2) << "ms";
            qDebug() << "  最小延迟:" << QString::number(minPipeline, 'f', 2) << "ms";
            qDebug() << "  最大延迟:" << QString::number(maxPipeline, 'f', 2) << "ms";
        }
        
        // 总延迟统计
        QList<double> totalLatencies;
        for (const auto &m : m_measurements) {
            if (m.totalLatency >= 0) {
                totalLatencies.append(m.totalLatency);
            }
        }
        
        if (!totalLatencies.isEmpty()) {
            double avgTotal = 0;
            double minTotal = totalLatencies.first();
            double maxTotal = totalLatencies.first();
            
            for (double lat : totalLatencies) {
                avgTotal += lat;
                if (lat < minTotal) minTotal = lat;
                if (lat > maxTotal) maxTotal = lat;
            }
            avgTotal /= totalLatencies.size();
            
            qDebug() << "\n总延迟统计:";
            qDebug() << "  平均延迟:" << QString::number(avgTotal, 'f', 2) << "ms";
            qDebug() << "  最小延迟:" << QString::number(minTotal, 'f', 2) << "ms";
            qDebug() << "  最大延迟:" << QString::number(maxTotal, 'f', 2) << "ms";
            
            // 延迟分析
            qDebug() << "\n延迟分析:";
            if (avgTotal < 100) {
                qDebug() << "  🟢 延迟水平: 优秀 (适合实时控制)";
            } else if (avgTotal < 300) {
                qDebug() << "  🟡 延迟水平: 良好 (适合一般监控)";
            } else {
                qDebug() << "  🔴 延迟水平: 较高 (可能影响实时性)";
            }
        }
        
        // 保存结果到文件
        saveResultsToFile();
        
        qDebug() << QString("=").repeated(60);
    }
    
    void saveResultsToFile()
    {
        QString filename = QString("advanced_rtsp_test_%1.json")
                          .arg(QDateTime::currentDateTime().toString("yyyyMMdd_hhmmss"));
        
        QJsonObject root;
        root["test_time"] = QDateTime::currentDateTime().toString(Qt::ISODateWithMs);
        root["rtsp_url"] = m_rtspUrl;
        
        QJsonArray measurementsArray;
        for (const auto &m : m_measurements) {
            QJsonObject obj;
            obj["timestamp"] = m.timestamp;
            obj["network_latency"] = m.networkLatency;
            obj["pipeline_latency"] = m.pipelineLatency;
            obj["total_latency"] = m.totalLatency;
            measurementsArray.append(obj);
        }
        root["measurements"] = measurementsArray;
        
        QJsonDocument doc(root);
        QFile file(filename);
        if (file.open(QIODevice::WriteOnly)) {
            file.write(doc.toJson(QJsonDocument::Indented));
            file.close();
            qDebug() << "\n测试结果已保存到:" << filename;
        }
    }
};

#include "advanced_rtsp_test.moc"

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    
    AdvancedRTSPLatencyTester tester;
    tester.runTest();
    
    return app.exec();
}